package io.modifier.basic.emo.permission

import android.view.View
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.DisposableEffectResult
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalView
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionState
import com.google.accompanist.permissions.PermissionStatus
import com.google.accompanist.permissions.rememberPermissionState
import com.google.accompanist.permissions.shouldShowRationale
import io.modifier.basic.emo.core.EmoLog
import kotlinx.coroutines.CoroutineScope

@OptIn(ExperimentalPermissionsApi::class)
private class EmoPermissionState(
    view: View,
    scope: CoroutineScope,
    tip: EmoPermissionTip,
    val permissionState: PermissionState,
) : PermissionState {

    private val modal = EmoPermissionModal(view, scope, tip)

    override val permission: String
        get() = permissionState.permission
    override val status: PermissionStatus
        get() = permissionState.status

    override fun launchPermissionRequest() {
        permissionState.launchPermissionRequest()
        modal.launch()
    }

    fun dismiss() {
        modal.dismiss()
    }

    fun showNotAvailableTip() {
        modal.showNotAvailableTip()
    }
}

private class PermissionCallbackActionHolder(
    var action: ((Boolean) -> Unit)? = null,
)

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun rememberEmoPermissionState(
    permission: String,
    tipContent: String,
    notAvailableContent: String = "",
    sureBtnString: String = "Sure",
    onPermissionResult: (Boolean) -> Unit = {},
): PermissionState {
    val tip = remember(tipContent) {
        SimpleEmoPermissionTip(tipContent, notAvailableContent, sureBtnString)
    }
    return rememberEmoPermissionState(permission, tip, onPermissionResult)
}

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun rememberEmoPermissionState(
    permission: String,
    tip: EmoPermissionTip,
    onPermissionResult: (Boolean) -> Unit = {},
): PermissionState {
    val callbackHolder = remember {
        PermissionCallbackActionHolder()
    }
    val permissionState = rememberPermissionState(permission) {
        EmoLog.d("测试", "权限  result:$it")
        callbackHolder.action?.invoke(it)
        onPermissionResult(it)
    }
    val view = LocalView.current
    val scope = rememberCoroutineScope()
    val emoPermissionState = remember(permissionState, tip) {
        EmoPermissionState(view, scope, tip, permissionState)
    }
    callbackHolder.action = {
        emoPermissionState.dismiss()
        if (permissionState.status.shouldShowRationale) {
            EmoLog.d("测试", "权限  shouldShowRationale")
        } else {
            EmoLog.d("测试", "权限  不可用")
            emoPermissionState.showNotAvailableTip()
        }
    }
    DisposableEffect(emoPermissionState) {
        object : DisposableEffectResult {
            override fun dispose() {
                EmoLog.d("测试", "权限  dispose")
                emoPermissionState.dismiss()
            }
        }
    }

    return emoPermissionState
}
